﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Web;
using Microsoft.Practices.Composite.Wpf.Commands;

namespace Infragistics.Composite.Wpf.Samples.SearchModule
{
    public class SearchViewModel : INotifyPropertyChanged
    {
        #region Fields

        const string SEARCH_BASE_URL = "http://search.live.com/results.aspx?q=";
        static readonly char[] SEPARATOR = new char[] { ' ' };

        DelegateCommand<object> _searchCommand;
        Uri _searchResultsUri;
        string _searchText = String.Empty;

        #endregion // Fields

        #region Constructor

        public SearchViewModel()
        {
        }

        #endregion // Constructor

        #region SearchCommand

        public DelegateCommand<object> SearchCommand
        {
            get 
            {
                if (_searchCommand == null)
                {
                    _searchCommand = new DelegateCommand<object>(
                        param => this.Search(),
                        param => this.CanSearch);
                }
                return _searchCommand; 
            }
        }

        void Search()
        {
            if (!this.CanSearch)
                throw new InvalidOperationException("Search cannot execute if CanSearch returns false.");

            string[] encodedKeywords =
                (from keyword in this.SearchText.Trim().Split(SEPARATOR, StringSplitOptions.RemoveEmptyEntries)
                 select HttpUtility.UrlEncode(keyword))
                .ToArray();

            string encodedQuery = String.Join("+", encodedKeywords);

            this.SearchResultsUri = new Uri(SEARCH_BASE_URL + encodedQuery, UriKind.Absolute);
        }

        bool CanSearch
        {
            get { return _searchText != null && _searchText.Trim().Length > 0; }
        }

        #endregion // SearchCommand

        #region SearchResultsUri

        public Uri SearchResultsUri
        {
            get { return _searchResultsUri; }
            set
            {
                if (value == _searchResultsUri)
                    return;

                _searchResultsUri = value;

                this.OnPropertyChanged("SearchResultsUri");
            }
        }

        #endregion // SearchResultsUri

        #region SearchText

        public string SearchText
        {
            get { return _searchText; }
            set
            {
                if (value == _searchText)
                    return;

                _searchText = value;

                this.SearchCommand.RaiseCanExecuteChanged();

                this.OnPropertyChanged("SearchText");
            }
        }

        #endregion // SearchText

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion // INotifyPropertyChanged Members
    }
}